package com.gwclh.personnel.shiro;

import com.gwclh.personnel.common.constants.UserConstants;
import com.gwclh.personnel.entity.User;
import com.gwclh.personnel.service.IUserService;
import com.gwclh.personnel.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;


@Slf4j
@Component
public class AccountRealm extends AuthorizingRealm {
    @Autowired
    JwtUtils jwtUtils;

    @Autowired
    IUserService userService;

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        AccountProfile accountProfile = (AccountProfile) principalCollection.getPrimaryPrincipal();
        String role = accountProfile.getRole();
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRole(role);
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        log.warn("AuthenticationInfo这个方法被调用");
        JwtToken jwt = (JwtToken)token;
        log.info("jwt---->{}",jwt);
        String userId = jwtUtils.getClaimByToken((String)jwt.getPrincipal()).getSubject();
        log.warn("userId"+userId);
        User user = null;
        Object object = redisTemplate.opsForValue().get(UserConstants.SHIRO_USER_REDIS_KEY+userId);
        if(object != null){
            user = (User) object;
        }else{
            user = userService.getById(userId);
            if(user!=null){
                User redisUser = new User();
                redisUser.setId(user.getId());
                redisUser.setRole(user.getRole());
                redisUser.setUsername(user.getUsername());
                redisUser.setAvatar(user.getAvatar());
                redisUser.setStatus(user.getStatus());
                redisTemplate.opsForValue().set(UserConstants.SHIRO_USER_REDIS_KEY+userId,redisUser, 1, TimeUnit.DAYS);
            }
        }
        if(user == null){
            throw new UnknownAccountException("账户不存在");
        }
        if(!user.getStatus()){
            throw new LockedAccountException("账户已被冻结");
        }
        AccountProfile profile = new AccountProfile();
        BeanUtils.copyProperties(user,profile);
        return new SimpleAuthenticationInfo(profile, jwt.getCredentials(), getName());
    }
}
